package com.minio.learning.example;

import com.minio.learning.client.MinioClientWrapper;
import com.minio.learning.config.MinioConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 * MinIO 基础操作示例
 * 
 * 这个类演示了 MinIO 的基本 CRUD 操作：
 * 1. 创建桶（Create Bucket）
 * 2. 上传文件（Upload File）
 * 3. 下载文件（Download File）
 * 4. 列出对象（List Objects）
 * 5. 删除对象（Delete Object）
 * 6. 删除桶（Delete Bucket）
 * 
 * 学习路径：
 * - 第一步：理解每个操作的作用
 * - 第二步：运行代码，观察结果
 * - 第三步：修改参数，尝试不同的操作
 */
public class BasicExample {
    
    private static final Logger logger = LoggerFactory.getLogger(BasicExample.class);
    
    public static void main(String[] args) {
        logger.info("====== MinIO 基础操作示例 ======\n");
        
        // 打印配置信息
        MinioConfig.printConfig();
        
        // 创建 MinIO 客户端
        MinioClientWrapper client = new MinioClientWrapper();
        
        // 桶名称
        String bucketName = "test-bucket";
        
        // ==================== 1. 创建桶 ====================
        logger.info("\n========== 步骤 1：创建桶 ==========");
        logger.info("💡 什么是桶？");
        logger.info("   - 类似文件系统中的顶级目录");
        logger.info("   - 用于组织和管理文件");
        logger.info("   - 每个桶名称必须唯一\n");
        
        client.createBucket(bucketName);
        
        // ==================== 2. 列出所有桶 ====================
        logger.info("\n========== 步骤 2：列出所有桶 ==========");
        client.listBuckets();
        
        // ==================== 3. 上传文件 ====================
        logger.info("\n========== 步骤 3：上传文件 ==========");
        logger.info("💡 为什么要上传文件？");
        logger.info("   - 将本地文件存储到 MinIO");
        logger.info("   - 可以随时随地访问");
        logger.info("   - 支持大文件和海量文件\n");
        
        // 创建测试文件
        String testFilePath = createTestFile("这是一个测试文件的内容\nMinIO 学习测试");
        
        // 上传文件
        // 参数说明：
        // - bucketName: 存储到哪个桶
        // - objectName: 存储后的文件名（可以包含路径，如 "docs/test.txt"）
        // - filePath: 本地文件路径
        client.uploadFile(bucketName, "test.txt", testFilePath);
        
        // 上传到"文件夹"中（实际上是对象名称包含斜杠）
        client.uploadFile(bucketName, "docs/readme.txt", testFilePath);
        client.uploadFile(bucketName, "images/sample.txt", testFilePath);
        
        // ==================== 4. 列出对象 ====================
        logger.info("\n========== 步骤 4：列出桶中的对象 ==========");
        logger.info("💡 什么是对象？");
        logger.info("   - 实际存储的文件");
        logger.info("   - 每个对象有唯一的名称（key）");
        logger.info("   - 可以通过名称访问\n");
        
        client.listObjects(bucketName);
        
        // 列出特定"文件夹"下的对象
        logger.info("\n列出 'docs/' 目录下的对象：");
        client.listObjects(bucketName, "docs/");
        
        // ==================== 5. 下载文件 ====================
        logger.info("\n========== 步骤 5：下载文件 ==========");
        
        String downloadPath = "downloads/test-downloaded.txt";
        client.downloadFile(bucketName, "test.txt", downloadPath);
        
        // ==================== 6. 检查对象是否存在 ====================
        logger.info("\n========== 步骤 6：检查对象是否存在 ==========");
        
        boolean exists = client.objectExists(bucketName, "test.txt");
        logger.info("对象 'test.txt' 存在吗？{}", exists ? "✅ 是" : "❌ 否");
        
        boolean notExists = client.objectExists(bucketName, "not-exist.txt");
        logger.info("对象 'not-exist.txt' 存在吗？{}", notExists ? "✅ 是" : "❌ 否");
        
        // ==================== 7. 获取对象信息 ====================
        logger.info("\n========== 步骤 7：获取对象信息 ==========");
        logger.info("💡 对象信息包含什么？");
        logger.info("   - 文件大小");
        logger.info("   - 上传时间");
        logger.info("   - 内容类型");
        logger.info("   - ETag（文件唯一标识）\n");
        
        client.getObjectInfo(bucketName, "test.txt");
        
        // ==================== 8. 复制对象 ====================
        logger.info("\n========== 步骤 8：复制对象 ==========");
        logger.info("💡 什么时候需要复制？");
        logger.info("   - 文件备份");
        logger.info("   - 重命名文件");
        logger.info("   - 跨桶移动\n");
        
        client.copyObject(bucketName, "test.txt", bucketName, "test-copy.txt");
        
        logger.info("\n复制后的对象列表：");
        client.listObjects(bucketName);
        
        // ==================== 9. 删除对象 ====================
        logger.info("\n========== 步骤 9：删除对象 ==========");
        logger.info("⚠️  注意：删除操作不可恢复！\n");
        
        client.deleteObject(bucketName, "test-copy.txt");
        client.deleteObject(bucketName, "images/sample.txt");
        
        logger.info("\n删除后的对象列表：");
        client.listObjects(bucketName);
        
        // ==================== 10. 清空桶并删除 ====================
        logger.info("\n========== 步骤 10：清空桶并删除 ==========");
        logger.info("💡 为什么要先清空？");
        logger.info("   - MinIO 不允许删除非空的桶");
        logger.info("   - 必须先删除所有对象\n");
        
        // 删除所有对象
        logger.info("正在删除所有对象...");
        for (String objectName : client.listObjects(bucketName)) {
            client.deleteObject(bucketName, objectName);
        }
        
        // 删除桶
        // client.deleteBucket(bucketName);  // 取消注释以删除桶
        
        logger.info("\n====== 基础操作示例完成！======");
        logger.info("💡 下一步：");
        logger.info("   1. 查看 AdvancedExample.java 学习高级功能");
        logger.info("   2. 修改代码，尝试不同的操作");
        logger.info("   3. 访问 http://localhost:9001 查看 Web 控制台");
        
        // 清理测试文件
        new File(testFilePath).delete();
    }
    
    /**
     * 创建测试文件
     * 
     * 为什么需要这个方法？
     * - 方便演示，不需要手动创建文件
     * - 自动生成测试数据
     */
    private static String createTestFile(String content) {
        try {
            File file = new File("test-upload.txt");
            FileWriter writer = new FileWriter(file);
            writer.write(content);
            writer.close();
            
            logger.info("✅ 测试文件创建成功: {}", file.getAbsolutePath());
            return file.getAbsolutePath();
            
        } catch (IOException e) {
            logger.error("❌ 创建测试文件失败: {}", e.getMessage());
            return null;
        }
    }
}

